home *** CD-ROM | disk | FTP | other *** search
/ X User Tools / X User Tools (O'Reilly and Associates)(1994).ISO / sources / libxpm / libxpm34.gz / libxpm34 / xpm-3.4 / lib / XpmCrBufFrI.c < prev    next >
C/C++ Source or Header  |  1994-03-14  |  8KB  |  326 lines

  1. /* Copyright 1989-94 GROUPE BULL -- See license conditions in file COPYRIGHT */
  2. /*****************************************************************************\
  3. * XpmCrBufFrI.c:                                                              *
  4. *                                                                             *
  5. *  XPM library                                                                *
  6. *  Scan an image and possibly its mask and create an XPM buffer               *
  7. *                                                                             *
  8. *  Developed by Arnaud Le Hors                                                *
  9. \*****************************************************************************/
  10.  
  11. #include "xpmP.h"
  12. #ifdef VMS
  13. #include "sys$library:string.h"
  14. #else
  15. #if defined(SYSV) || defined(SVR4)
  16. #include <string.h>
  17. #else
  18. #include <strings.h>
  19. #endif
  20. #endif
  21.  
  22. LFUNC(WriteColors, int, (char **dataptr, unsigned int *data_size,
  23.              unsigned int *used_size, XpmColor *colors,
  24.              unsigned int ncolors, unsigned int cpp));
  25.  
  26. LFUNC(WritePixels, void, (char *dataptr, unsigned int *used_size,
  27.               unsigned int width, unsigned int height,
  28.               unsigned int cpp, unsigned int *pixels,
  29.               XpmColor *colors));
  30.  
  31. LFUNC(WriteExtensions, void, (char *dataptr, unsigned int *used_size,
  32.                   XpmExtension *ext, unsigned int num));
  33.  
  34. LFUNC(ExtensionsSize, int, (XpmExtension *ext, unsigned int num));
  35. LFUNC(CommentsSize, int, (XpmInfo *info));
  36.  
  37. int
  38. XpmCreateBufferFromImage(display, buffer_return, image, shapeimage, attributes)
  39.     Display *display;
  40.     char **buffer_return;
  41.     XImage *image;
  42.     XImage *shapeimage;
  43.     XpmAttributes *attributes;
  44. {
  45.     XpmImage xpmimage;
  46.     XpmInfo info;
  47.     int ErrorStatus;
  48.  
  49.     /* initialize return value */
  50.     if (buffer_return)
  51.     *buffer_return = NULL;
  52.  
  53.     /* create an XpmImage from the image */
  54.     ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
  55.                          &xpmimage, attributes);
  56.     if (ErrorStatus != XpmSuccess)
  57.     return (ErrorStatus);
  58.  
  59.     /* create the buffer from the XpmImage */
  60.     if (attributes) {
  61.     xpmSetInfo(&info, attributes);
  62.     ErrorStatus =
  63.         XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, &info);
  64.     } else
  65.     ErrorStatus =
  66.         XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, NULL);
  67.  
  68.     /* free the XpmImage */
  69.      XpmFreeXpmImage(&xpmimage);
  70.  
  71.     return (ErrorStatus);
  72. }
  73.  
  74.  
  75. #undef RETURN
  76. #define RETURN(status) \
  77. { \
  78.     if (ptr) \
  79.     XpmFree(ptr); \
  80.     return(status); \
  81. }
  82.  
  83. int
  84. XpmCreateBufferFromXpmImage(buffer_return, image, info)
  85.     char **buffer_return;
  86.     XpmImage *image;
  87.     XpmInfo *info;
  88. {
  89.     /* calculation variables */
  90.     int ErrorStatus;
  91.     char buf[BUFSIZ];
  92.     unsigned int cmts, extensions, ext_size = 0;
  93.     unsigned int l, cmt_size = 0;
  94.     char *ptr = NULL, *p;
  95.     unsigned int ptr_size, used_size;
  96.  
  97.     *buffer_return = NULL;
  98.  
  99.     cmts = info && (info->valuemask & XpmComments);
  100.     extensions = info && (info->valuemask & XpmExtensions)
  101.     && info->nextensions;
  102.  
  103.     /* compute the extensions and comments size */
  104.     if (extensions)
  105.     ext_size = ExtensionsSize(info->extensions, info->nextensions);
  106.     if (cmts)
  107.     cmt_size = CommentsSize(info);
  108.  
  109.     /* write the header line */
  110.     sprintf(buf, "/* XPM */\nstatic char * image_name[] = {\n");
  111.     used_size = strlen(buf);
  112.     ptr_size = used_size + ext_size + cmt_size + 1;
  113.     ptr = (char *) XpmMalloc(ptr_size);
  114.     if (!ptr)
  115.     return XpmNoMemory;
  116.     strcpy(ptr, buf);
  117.  
  118.     /* write the values line */
  119.     if (cmts && info->hints_cmt) {
  120.     sprintf(ptr + used_size, "/*%s*/\n", info->hints_cmt);
  121.     used_size += strlen(info->hints_cmt) + 5;
  122.     }
  123.     sprintf(buf, "\"%d %d %d %d", image->width, image->height,
  124.         image->ncolors, image->cpp);
  125.     l = strlen(buf);
  126.  
  127.     if (info && (info->valuemask & XpmHotspot)) {
  128.     sprintf(buf + l, " %d %d", info->x_hotspot, info->y_hotspot);
  129.     l = strlen(buf);
  130.     }
  131.     if (extensions) {
  132.     sprintf(buf + l, " XPMEXT");
  133.     l = strlen(buf);
  134.     }
  135.     sprintf(buf + l, "\",\n");
  136.     l = strlen(buf);
  137.     ptr_size += l;
  138.     p = (char *) XpmRealloc(ptr, ptr_size);
  139.     if (!p)
  140.     RETURN(XpmNoMemory);
  141.     ptr = p;
  142.     strcpy(ptr + used_size, buf);
  143.     used_size += l;
  144.  
  145.     /* write colors */
  146.     if (cmts && info->colors_cmt) {
  147.     sprintf(ptr + used_size, "/*%s*/\n", info->colors_cmt);
  148.     used_size += strlen(info->colors_cmt) + 5;
  149.     }
  150.     ErrorStatus = WriteColors(&ptr, &ptr_size, &used_size,
  151.                   image->colorTable, image->ncolors, image->cpp);
  152.  
  153.     if (ErrorStatus != XpmSuccess)
  154.     RETURN(ErrorStatus);
  155.  
  156.     /*
  157.      * now we know the exact size we needed, realloc the data 4 = 1 (for
  158.      * '"') + 3 (for '",\n') 1 = - 2 is because the last line does not end
  159.      * with ',\n' + 3 (for '};\n')
  160.      */
  161.     ptr_size += image->height * (image->width * image->cpp + 4) + 1;
  162.  
  163.     p = (char *) XpmRealloc(ptr, ptr_size);
  164.     if (!p)
  165.     RETURN(XpmNoMemory);
  166.     ptr = p;
  167.  
  168.     /* print pixels */
  169.     if (cmts && info->pixels_cmt) {
  170.     sprintf(ptr + used_size, "/*%s*/\n", info->pixels_cmt);
  171.     used_size += strlen(info->pixels_cmt) + 5;
  172.     }
  173.     WritePixels(ptr + used_size, &used_size, image->width, image->height,
  174.         image->cpp, image->data, image->colorTable);
  175.  
  176.     /* print extensions */
  177.     if (extensions)
  178.     WriteExtensions(ptr + used_size, &used_size,
  179.             info->extensions, info->nextensions);
  180.  
  181.     /* close the array */
  182.     sprintf(ptr + used_size, "};\n");
  183.  
  184.     *buffer_return = ptr;
  185.  
  186.     return (XpmSuccess);
  187. }
  188.  
  189. static int
  190. WriteColors(dataptr, data_size, used_size, colors, ncolors, cpp)
  191.     char **dataptr;
  192.     unsigned int *data_size;
  193.     unsigned int *used_size;
  194.     XpmColor *colors;
  195.     unsigned int ncolors;
  196.     unsigned int cpp;
  197. {
  198.     char buf[BUFSIZ];
  199.     unsigned int a, key, l;
  200.     char *s, *s2;
  201.     char **defaults;
  202.  
  203.     *buf = '"';
  204.     for (a = 0; a < ncolors; a++, colors++) {
  205.  
  206.     defaults = (char **) colors;
  207.     s = buf + 1;
  208.     strncpy(s, *defaults++, cpp);
  209.     s += cpp;
  210.  
  211.     for (key = 1; key <= NKEYS; key++, defaults++) {
  212.         if (s2 = *defaults) {
  213.         sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
  214.         s += strlen(s);
  215.         }
  216.     }
  217.     strcpy(s, "\",\n");
  218.     l = strlen(buf);
  219.     s = (char *) XpmRealloc(*dataptr, *data_size + l);
  220.     if (!s)
  221.         return (XpmNoMemory);
  222.     *data_size += l;
  223.     strcpy(s + *used_size, buf);
  224.     *used_size += l;
  225.     *dataptr = s;
  226.     }
  227.     return (XpmSuccess);
  228. }
  229.  
  230. static void
  231. WritePixels(dataptr, used_size, width, height, cpp, pixels, colors)
  232.     char *dataptr;
  233.     unsigned int *used_size;
  234.     unsigned int width;
  235.     unsigned int height;
  236.     unsigned int cpp;
  237.     unsigned int *pixels;
  238.     XpmColor *colors;
  239. {
  240.     char *s = dataptr;
  241.     unsigned int x, y, h;
  242.  
  243.     h = height - 1;
  244.     for (y = 0; y < h; y++) {
  245.     *s++ = '"';
  246.     for (x = 0; x < width; x++, pixels++) {
  247.         strncpy(s, colors[*pixels].string, cpp);
  248.         s += cpp;
  249.     }
  250.     strcpy(s, "\",\n");
  251.     s += 3;
  252.     }
  253.     /* duplicate some code to avoid a test in the loop */
  254.     *s++ = '"';
  255.     for (x = 0; x < width; x++, pixels++) {
  256.     strncpy(s, colors[*pixels].string, cpp);
  257.     s += cpp;
  258.     }
  259.     *s++ = '"';
  260.     *used_size += s - dataptr;
  261. }
  262.  
  263. static int
  264. ExtensionsSize(ext, num)
  265.     XpmExtension *ext;
  266.     unsigned int num;
  267. {
  268.     unsigned int x, y, a, size;
  269.     char **line;
  270.  
  271.     size = 0;
  272.     for (x = 0; x < num; x++, ext++) {
  273.     /* 11 = 10 (for ',\n"XPMEXT ') + 1 (for '"') */
  274.     size += strlen(ext->name) + 11;
  275.     a = ext->nlines;
  276.     for (y = 0, line = ext->lines; y < a; y++, line++)
  277.         /* 4 = 3 (for ',\n"') + 1 (for '"') */
  278.         size += strlen(*line) + 4;
  279.     }
  280.     /* 13 is for ',\n"XPMENDEXT"' */
  281.     return size + 13;
  282. }
  283.  
  284. static void
  285. WriteExtensions(dataptr, used_size, ext, num)
  286.     char *dataptr;
  287.     unsigned int *used_size;
  288.     XpmExtension *ext;
  289.     unsigned int num;
  290. {
  291.     unsigned int x, y, a;
  292.     char **line;
  293.     char *s = dataptr;
  294.  
  295.     for (x = 0; x < num; x++, ext++) {
  296.     sprintf(s, ",\n\"XPMEXT %s\"", ext->name);
  297.     s += strlen(ext->name) + 11;
  298.     a = ext->nlines;
  299.     for (y = 0, line = ext->lines; y < a; y++, line++) {
  300.         sprintf(s, ",\n\"%s\"", *line);
  301.         s += strlen(*line) + 4;
  302.     }
  303.     }
  304.     strcpy(s, ",\n\"XPMENDEXT\"");
  305.     *used_size += s - dataptr + 13;
  306. }
  307.  
  308. static int
  309. CommentsSize(info)
  310.     XpmInfo *info;
  311. {
  312.     int size = 0;
  313.  
  314.     /* 5 = 2 (for "/_*") + 3 (for "*_/\n") */
  315.     if (info->hints_cmt)
  316.     size += 5 + strlen(info->hints_cmt);
  317.  
  318.     if (info->colors_cmt)
  319.     size += 5 + strlen(info->colors_cmt);
  320.  
  321.     if (info->pixels_cmt)
  322.     size += 5 + strlen(info->pixels_cmt);
  323.  
  324.     return size;
  325. }
  326.